import React from 'react';
import {Spin, Card, Button, Row, Col, Table, Form, Modal, Input, message as msg} from 'antd';
import PropTypes from 'prop-types';
import routes from './routes';
import {FORM_OPTIONS, TABLE, DATE_FORMAT, FIXED_COLUMN_WIDTH, FORM_BIG_OPTIONS, FORM_ROW_OPTIONS} from '../constants';
import {PERMISSION} from './constants';
import {hasPermissions} from './utils';
import {injectIntl, language} from './intl';
import {conventEnumValueToString, formatDateTime, formatAmount} from '../utils';
import styles from './style.css';
import PartInvoiceDetailPanel from './PartInvoiceDetailPanel';
import PartInvoicePanel from './PartInvoicePanel';
import SearchInput from 'Shared/components/SearchInput';
import TextInput from 'Shared/components/TextInput';
import WrappedSelect from '../common/WrappedSelect';
import WrappedDatePicker from '../common/WrappedDatePicker';
import LocalizeInputNumber from '../common/LocalizeInputNumber';
import DropdownMenu from 'Shared/components/DropdownMenu';
import Return from '../common/Return';
import {newOrUpdateValidator} from './validator';
import {getDetail} from './api';
import FileUpload from './FileUpload';
import {partClaimType, currency, partClaimReasonStatus} from '../Enum';

const date = new Date();
const FormItem = Form.Item;
const partClaimReasonStatusList = partClaimReasonStatus.toList(language);
const claimTypeList = partClaimType.toList(language);
class NewPanel extends React.PureComponent {
    state = {
        loading: false,
        hasOperat: false,
        data: {},
        showPartInvoicePanel: false,
        showPartInvoiceDetailPanel: false,
        details: [],
        showFile: false,
        errorDetails: []
    }
    componentDidMount() {
        this.getDetailInfo();
    }
    
    componentWillUnmount() {
        this.isunmount = true;
    }
    isEngineCheck = e => {
        const isEngine = e.target.checked;
        this.setState({
            data: Object.assign({}, this.state.data, {
                isEngine
            })
        });
    }
    getDetailInfo = () => {
        if(this.props.id)
            getDetail(this.props.id)
                .then(res => {
                    if(res.ok)
                        this.setState({
                            isFetching: false,
                            data: res.data,
                            details: res.data.details
                        });
                    else
                        this.setState(({
                            isFetching: false
                        }));
                });
    }
    claimReasonChange = (claimReason, id) => {
        const details = this.state.details || [];
        const tmp = details.map(d => {
            if(d.invoicePackingListDetailId === id)
                return Object.assign({}, d, {
                    claimReason
                });
            return d;
        });
        this.setState({
            details: tmp,
            hasOperat: true
        });
    }
    onChange = (value, name) => {
        const data = Object.assign({}, this.state.data, {
            [name]: value
        });
        this.setState({
            data,
            hasOperat: true
        });
    }
    onSelectInvoice = records => {
        this.setState({
            data: Object.assign({}, this.state.data, {
                partInvoiceId: records.id,
                invoiceCode: records.code,
                invoicedDate: records.invoicedDate,
                shipmentDate: records.shipmentDate,
                actualArrivalDate: records.actualArrivalDate,
                destination: records.destination
            }),
            hasOperat: true,
            showPartInvoicePanel: false
        });
    }
    onClickSearchBtn = () => {
        if(!this.state.data.brandId)
            return msg.warn(this.props.intl.formatMessage({
                id: 'newPanel.message.brand',
                defaultMessage: '请选择品牌'
            }));
        this.setState({showPartInvoicePanel: true});
    }
    onClosePartInvoicePanel = () => {
        this.setState({showPartInvoicePanel: false});
    }
    onClickOkOnPopconfirm = () => {
        this.props.onCancel();
    }
    onSubmit = () => {
        const {data, details} = this.state;
        const isValid = newOrUpdateValidator(data, details);
        if(!isValid) {
            this.setState({
                validate: true
            });
            return;
        }
        this.setState({loading: true});
        this.props.onSubmit(data, details).then(res => {
            if(res.success)
                this.props.successReturn();
            if(!this.isunmount)
                this.setState({loading: false});
        });
    }
    onUpdateClaimAmount = (claimAmount, id) => {
        const details = this.state.details || [];
        const tmp = details.map(d => {
            if(d.invoicePackingListDetailId === id)
                return Object.assign({}, d, {
                    claimAmount,
                    claimFee: claimAmount * d.price
                });
            return d;
        });
        this.setState({
            details: tmp,
            hasOperat: true
        });
    }
    onChangeBrand = (value, name) => {
        if(this.state.data.brandId !== undefined && this.state.data.brandId !== value)
            Modal.confirm({
                title: this.props.intl.formatMessage({
                    id: 'newPanel.message.switch2',
                    defaultMessage: '提示'
                }),
                content: this.props.intl.formatMessage({
                    id: 'newPanel.message.switch',
                    defaultMessage: '变更品牌，将会清空清单数据，是否清空？'
                }),
                onOk: () => this.onChangeSwitch(value, name)
            });
        else
            this.setState({
                data: Object.assign({}, this.state.data, {
                    [name]: value
                }),
                hasOperat: true
            });
    }
    onChangeSwitch = (value, name) => {
        const data = Object.assign({}, this.state.data, {
            [name]: value,
            partInvoiceId: undefined,
            invoiceCode: undefined,
            invoicedDate: undefined,
            shipmentDate: undefined,
            actualArrivalDate: undefined,
            destination: undefined
        });
        this.setState({
            data,
            details: [],
            hasOperat: true
        });
    }
    onDeleteDetail = e => {
        const id = e.target.dataset.id;
        const tmp = this.state.details.filter(d => d.invoicePackingListDetailId !== id);
        this.setState({
            details: [...tmp],
            hasOperat: true
        });
    }
    onClickUpload = e => {
        const id = e.target.dataset.id;
        this.setState({
            currentDetailId: id,
            showFile: true
        });
    };
    onCloseFileModal = () => {
        this.setState({
            showFile: false,
            currentDetailId: '',
        });
    };
    onChangeUpload = data => {
        const details = this.state.errorDetails.filter(item => !(item.invoicePackingListDetailId === this.state.currentDetailId));
        this.setState({
            hasOperat: true,
            errorDetails: details
        });
        this.onUpdateAttachments(data, this.state.currentDetailId);
    }
    onRemove = data => {
        const {details = []} = this.state;
        const {attachments = []} = details.find(item => item.invoicePackingListDetailId === this.state.currentDetailId) || {};
        const errorDetails = attachments.length - 1 <= 0 ? [...this.state.errorDetails, {
            id: this.state.currentDetailId
        }] : this.state.errorDetails;
        this.setState({
            hasOperat: true,
            errorDetails
        });
        this.onRemoveAttachments(data, this.state.currentDetailId);
    }
    onUpdateAttachments = (data, currentDetailId) => {
        const details = this.state.details || [];
        let attachments = [];
        const tmp = details.map(d => {
            if(d.invoicePackingListDetailId === currentDetailId) {
                attachments = d.attachments || [];
                attachments.push({
                    fileId: data.id,
                    fileName: data.fileName
                });
                return Object.assign({}, d, {
                    attachments: [...attachments]
                });
            }
            return d;
        });
        this.setState({
            details: tmp,
            hasOperat: true
        });
    }
    onRemoveAttachments = (data, currentDetailId) => {
        const details = this.state.details || [];
        let attachments = [];
        const tmp = details.map(d => {
            if(d.invoicePackingListDetailId === currentDetailId) {
                attachments = d.attachments || [];
                attachments.splice({
                    fileId: data.id,
                    fileName: data.fileName
                }, 1);
                return Object.assign({}, d, {
                    attachments: [...attachments]
                });
            }
            return d;
        });
        this.setState({
            details: tmp,
            hasOperat: true
        });
    }
    onClickAddBtn = () => {
        this.setState({showPartInvoiceDetailPanel: true});
    }
    onSelectPartInvoiceDetail = records => {
        const retailDetails = this.state.details || [];
        records.forEach(r => {
            const index = retailDetails.findIndex(v => v.invoicePackingListDetailId === r.id);
            if(index === -1)
                retailDetails.push({
                    invoicePackingListDetailId: r.id,
                    partId: r.partId,
                    partCode: r.partCode,
                    partName: r.partName,
                    packingListCode: r.packingListCode,
                    partSaleOrderCode: r.partSaleOrderCode,
                    price: r.price,
                    quantity: r.quantity,
                    claimAmount: 1,
                    claimFee: r.price,
                    palletCode: r.palletCode,
                });
        });
        this.setState({
            details: [...retailDetails],
            hasOperat: true,
            showPartInvoiceDetailPanel: false,
            isAlert: true
        });
    }
    onClosePartInvoiceDetailPanel = () => {
        this.setState({showPartInvoiceDetailPanel: false});
    }
    render() {
        const {formatMessage} = this.props.intl;
        const {data, details, loading} = this.state;
        const {id, enterprise, initEnum} = this.props;
        const validateBrandId = !data.brandId && this.state.validate ? 'error' : null;
        const validateInvoiceCode = !data.invoiceCode && this.state.validate ? 'error' : null;
        const validateReceiptDate = !data.receiptDate && this.state.validate ? 'error' : null;
        const validateClaimType = !data.claimType && this.state.validate ? 'error' : null;
        const validateRemark = data.remark && data.remark.length > 100 && this.state.validate ? 'error' : null;
        const submitable = !hasPermissions(PERMISSION.add, this.props.permissions) || !hasPermissions(PERMISSION.update, this.props.permissions);
        const {attachments = []} = details.find(item => item.invoicePackingListDetailId === this.state.currentDetailId) || {};
        const currentSelectRowkeys = details.map(item => item.invoicePackingListDetailId);
        let claimFee = 0;
        let claimAmount = 0;
        if(details.length > 0)
            details.forEach(v => {
                claimFee += v.claimFee;
                claimAmount += v.claimAmount;
            });
        const colums = [{
            title: formatMessage({
                id: 'newPanel.column.palletCode',
                defaultMessage: '托盘号'
            }),
            dataIndex: 'palletCode',
        }, {
            title: formatMessage({
                id: 'newPanel.column.partSaleOrderCode',
                defaultMessage: '备件销售订单编号'
            }),
            dataIndex: 'partSaleOrderCode',
        }, {
            title: formatMessage({
                id: 'newPanel.column.partCode',
                defaultMessage: '备件编号'
            }),
            dataIndex: 'partCode',
        }, {
            title: formatMessage({
                id: 'newPanel.column.partName',
                defaultMessage: '备件名称'
            }),
            dataIndex: 'partName',
        }, {
            title: formatMessage({
                id: 'newPanel.column.quantity',
                defaultMessage: '销售数量'
            }),
            dataIndex: 'quantity',
        }, {
            title: formatMessage({
                id: 'newPanel.column.price',
                defaultMessage: '备件单价'
            }),
            dataIndex: 'price',
            render: text => formatAmount(text)
        }, {
            title: formatMessage({
                id: 'newPanel.column.claimAmount',
                defaultMessage: '索赔数量'
            }),
            dataIndex: 'claimAmount',
            width: 145,
            render: (text, record) => {
                const validate = (!text || text === undefined) || text === 0 ? {validateStatus: 'error'} : null;
                return (
                    <FormItem {...validate}>
                        <LocalizeInputNumber
                            min={1}
                            max={record.quantity}
                            id={record.invoicePackingListDetailId}
                            precision={0}
                            value={text} onBlur={this.onUpdateClaimAmount}/>
                    </FormItem>
                );
            }
        }, {
            title: formatMessage({
                id: 'newPanel.column.claimFee',
                defaultMessage: '索赔金额'
            }),
            dataIndex: 'claimFee',
            render: text => formatAmount(text)
        }, {
            title: formatMessage({
                id: 'newPanel.column.claimReason',
                defaultMessage: '索赔原因'
            }),
            dataIndex: 'claimReason',
            render: (text, record) => {
                const validate = (!text || text === undefined) ? {validateStatus: 'error'} : null;
                return (
                    <FormItem {...validate}>
                        <WrappedSelect
                            allowClear
                            id={record.invoicePackingListDetailId}
                            value={record.claimReason}
                            options={partClaimReasonStatusList}
                            onChange={this.claimReasonChange} />
                    </FormItem>
                );
            }
        }, {
            title: formatMessage({
                id: 'newPanel.column.packingListCode',
                defaultMessage: '箱单号'
            }),
            dataIndex: 'packingListCode',
        }, {
            title: formatMessage({
                id: 'newPanel.column.action',
                defaultMessage: '操作'
            }),
            dataIndex: 'invoicePackingListDetailId',
            fixed: 'right',
            width: FIXED_COLUMN_WIDTH,
            render: (text, record) => {
                const menus = [
                    {
                        id: 'delete',
                        children: (
                            <a key="delete" data-id={text} onClick={this.onDeleteDetail}>
                                {this.props.intl.formatMessage({
                                    id: 'add.delete',
                                    defaultMessage: '删除'
                                })}
                            </a>
                        ),
                    }, {
                        id: 'upload',
                        children: (
                            <a key="upload" data-id={text} onClick={this.onClickUpload}>
                                {this.props.intl.formatMessage({
                                    id: 'add.upload',
                                    defaultMessage: '附件管理'
                                })}
                            </a>
                        ),
                    }
                ];
                return <DropdownMenu key={record.invoicePackingListDetailId} menus={menus} primaryLength={1} id={record.invoicePackingListDetailId} />;
            }
        }];
        return (
            <div className="form-standard">
                <Modal
                    title={this.props.intl.formatMessage({
                        id: 'newPanel.file.modal.title',
                        defaultMessage: '附件管理'
                    })}
                    width="60%"
                    maskClosable={false}
                    footer={null}
                    wrapClassName={styles.dataSelectModal}
                    destroyOnClose={true}
                    visible={this.state.showFile}
                    onCancel={this.onCloseFileModal}>
                    <Row>
                        <Col {...FORM_BIG_OPTIONS.col}>
                            <FileUpload onChange={this.onChangeUpload} onRemove={this.onRemove} fileList={attachments} />
                        </Col>
                    </Row>
                </Modal>
                <Spin spinning={this.state.loading}>
                    <Card title={formatMessage({
                        id: 'newPanel.column.common',
                        defaultMessage: '订单基本信息'
                    })}>
                        <Form>
                            <Row>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.code',
                                        defaultMessage: '编号'
                                    })}
                                    {...FORM_OPTIONS.item} >
                                        <Input placeholder={formatMessage({
                                            id: 'newPanel.operation.notGenerate',
                                            defaultMessage: '尚未生成'
                                        })} value={data.code} disabled />
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem
                                        label={formatMessage({
                                            id: 'newPanel.operation.brandId',
                                            defaultMessage: '品牌'
                                        })}
                                        {...FORM_OPTIONS.item}
                                        validateStatus={validateBrandId}
                                        required>
                                        <WrappedSelect
                                            name="brandId"
                                            options={initEnum.brands}
                                            value={data.brandId}
                                            onChange={this.onChangeBrand} />
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.invoiceCode',
                                        defaultMessage: '发票号'
                                    })} {...FORM_OPTIONS.item}
                                    validateStatus={validateInvoiceCode}
                                    required>
                                        <SearchInput
                                            disabled={true}
                                            value={data.invoiceCode}
                                            id={data.partInvoiceId}
                                            onClickSearchBtn={this.onClickSearchBtn} />
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem
                                        label={this.props.intl.formatMessage({
                                            id: 'newPanel.operation.claimType',
                                            defaultMessage: '索赔类型'
                                        })}
                                        {...FORM_OPTIONS.item}
                                        validateStatus={validateClaimType}
                                        required>
                                        <WrappedSelect
                                            allowClear
                                            name="claimType"
                                            value={data.claimType}
                                            options={claimTypeList}
                                            onChange={this.onChange} />
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem
                                        label={this.props.intl.formatMessage({
                                            id: 'newPanel.form.receiptDate',
                                            defaultMessage: '收货日期'
                                        })}
                                        {...FORM_OPTIONS.item}
                                        validateStatus={validateReceiptDate}
                                        required>
                                        <WrappedDatePicker
                                            name="receiptDate"
                                            value={data.receiptDate}
                                            onChange={this.onChange}/>
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.dealerCode',
                                        defaultMessage: '总代编号'
                                    })} {...FORM_OPTIONS.item}>
                                        {enterprise && (id ? data.dealerCode : enterprise.code)}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.dealerName',
                                        defaultMessage: '总代名称'
                                    })} {...FORM_OPTIONS.item}>
                                        {enterprise && (id ? data.dealerName : enterprise.name)}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.address',
                                        defaultMessage: '地址'
                                    })} {...FORM_OPTIONS.item}>
                                        {enterprise && (id ? data.address : enterprise.address)}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.contactNumber',
                                        defaultMessage: '联系电话'
                                    })} {...FORM_OPTIONS.item}>
                                        {enterprise && (id ? data.contactNumber : enterprise.contactNumber)}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.currency',
                                        defaultMessage: '币种'
                                    })} {...FORM_OPTIONS.item}>
                                        {enterprise && (conventEnumValueToString(currency, id ? data.currency : enterprise.currency))}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem
                                        label={this.props.intl.formatMessage({
                                            id: 'newPanel.form.createTime',
                                            defaultMessage: '提报日期'
                                        })}
                                        {...FORM_OPTIONS.item}>
                                        {formatDateTime(id ? data.createTime : date, DATE_FORMAT)}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.claimAmount',
                                        defaultMessage: '索赔总数量'
                                    })} {...FORM_OPTIONS.item}>
                                        {claimAmount}
                                    </FormItem>
                                </Col>
                                <Col {...FORM_OPTIONS.col}>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.claimFee',
                                        defaultMessage: '索赔总金额'
                                    })} {...FORM_OPTIONS.item}>
                                        {formatAmount(claimFee)}
                                    </FormItem>
                                </Col>
                            </Row>
                            <Row>
                                <Col>
                                    <FormItem label={formatMessage({
                                        id: 'newPanel.operation.remark',
                                        defaultMessage: '备注'
                                    })} {...FORM_ROW_OPTIONS.item} validateStatus={validateRemark}>
                                        <TextInput
                                            type="textarea"
                                            name="remark"
                                            value={data.remark}
                                            onBlur={this.onChange} />
                                    </FormItem>
                                </Col>
                            </Row>
                        </Form>
                    </Card>
                    <Card
                        title={formatMessage({
                            id: 'newPanel.operation.detail',
                            defaultMessage: '订单清单'
                        })}
                        extra={<div>
                            <Button
                                size="small"
                                disabled={!data.partInvoiceId}
                                onClick={this.onClickAddBtn}>
                                {formatMessage({
                                    id: 'newPanel.operation.newDetail',
                                    defaultMessage: '添加备件'
                                })}
                            </Button>
                        </div>}>
                        <Table
                            className="white-space-nowrap"
                            columns={colums}
                            rowKey="invoicePackingListDetailId"
                            pagination={false}
                            dataSource={details}
                            {...TABLE} />
                    </Card>
                    <Card className={styles.optionBtn}>
                        <Button
                            type="primary"
                            onClick={this.onSubmit}
                            disabled={!submitable}
                            loading={loading}>
                            {formatMessage({
                                id: 'newPanel.operation.save',
                                defaultMessage: '保存'
                            })}
                        </Button>
                    </Card>
                    {
                        this.state.showPartInvoicePanel &&
                        <PartInvoicePanel
                            brandId={data.brandId}
                            dealerId={enterprise && (enterprise.id)}
                            selectKey={data.id}
                            onCancel={this.onClosePartInvoicePanel}
                            onSelect={this.onSelectInvoice} />
                    }
                    {
                        this.state.showPartInvoiceDetailPanel &&
                        <PartInvoiceDetailPanel
                            currentSelectRowkeys={currentSelectRowkeys}
                            partInvoiceId={data.partInvoiceId}
                            partInvoiceCode={data.invoiceCode}
                            selectKey={data.id}
                            onCancel={this.onClosePartInvoiceDetailPanel}
                            onSelect={this.onSelectPartInvoiceDetail} />
                    }
                </Spin>
                <div className="page-toolbar">
                    <Return
                        disabled={this.state.loading}
                        onConfirm={this.onClickOkOnPopconfirm}
                        showWarning={this.state.hasOperat} />
                </div>
            </div>
        );
    }
}

NewPanel.propTypes = {
    initEnum: PropTypes.object.isRequired,
    permissions: PropTypes.array.isRequired,
    successReturn: PropTypes.func.isRequired,
    onCancel: PropTypes.func.isRequired,
    onSubmit: PropTypes.func.isRequired,
    enterprise: PropTypes.object,
    history: PropTypes.object,
    id: PropTypes.string,
    intl: PropTypes.object,
    isDealerUser: PropTypes.bool,
};

import {connect} from 'react-redux';
import {
    tableSearch,
    onNewOrUpdate
} from './actions';
import selectorFactory from 'Shared/utils/immutableToJsSelectorFactory';
import {createSelector} from 'reselect';
const getinitEnumData = createSelector(
    state => state.getIn(['page', 'domainData', 'initData']),
    init => {
        const initData = init.toJS();
        const brands = initData.brands ? initData.brands.map(item => ({
            text: `${'('}${item.code}${')'}${item.name}`,
            value: item.id
        })) : [];
        return {
            brands
        };
    }
);

const getPermissions = selectorFactory(['page', 'domainData', 'permission', 'data']);
const getEnterprise = selectorFactory(['page', 'domainData', 'initData', 'enterprise']);
const mapStateToProps = (state, props) => ({
    isDealerUser: state.getIn((['page', 'domainData', 'initData', 'isDealerUser'])),
    permissions: getPermissions(state),
    initEnum: getinitEnumData(state),
    enterprise: getEnterprise(state),
});
const mapDispatchToProps = (dispatch, props) => ({
    onSubmit: (data, details) => dispatch(onNewOrUpdate(data, details)),
    successReturn: () => {
        dispatch(tableSearch());
        props.history.push(routes.query.url());
    },
    onCancel: () => {
        props.history.push(routes.query.url());
    },
});
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(NewPanel));
